package com.wx.tnsadmin.config;


import com.wx.tnsadmin.componment.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private RestfulAccessDeniedHandler restfulAccessDeniedHandler;

    @Autowired
    private RestAuthenticationEntryPoint restAuthenticationEntryPoint;


    @Autowired
    public void configureGlobal ( AuthenticationManagerBuilder auth ) throws Exception {
        auth.userDetailsService ( userDetailsService )
                .passwordEncoder ( passwordEncoder ( ) );
    }

    private PasswordEncoder passwordEncoder () {
        return new BCryptPasswordEncoder ( );
    }

    @Bean
    public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter () {
        return new JwtAuthenticationTokenFilter ( );
    }

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean () throws Exception {
        return super.authenticationManagerBean ( );
    }



    @Override
    protected void configure ( HttpSecurity http ) throws Exception {
        http.csrf ( ).disable ( );

        http
                .sessionManagement ( )// 基于token，所以不需要session
                .sessionCreationPolicy ( SessionCreationPolicy.STATELESS )
                .and ( )
                .authorizeRequests ( )
                .antMatchers (
                        HttpMethod.GET,
                        "/",
                        "/*.html",
                        "/favicon.ico",
                        "/**/*.html",
                        "/**/*.css",
                        "/**/*.js",
                        "/swagger-resources/**",
                        "/v2/api-docs/**" )
                .permitAll ( ) //都可以访问
                .antMatchers ( "/admin/loginAdmin" )
                .permitAll ( )
                .antMatchers("/log/**").hasAnyAuthority ("tns:log:findByLogPage")
                .antMatchers("/menu/**").hasAnyAuthority ("tns:menu:findAllMenu")
                .antMatchers("/role/**").hasAnyAuthority ("tns:role:findAllRole")
                .antMatchers("/auth/**").hasAnyAuthority ("tns:auth:findAllAuth")
                .antMatchers ( HttpMethod.OPTIONS )//跨域请求会先进行一次options请求
                .permitAll ( )
                .anyRequest ( )
                .authenticated ( );

        // 禁用缓存
        http.headers ( ).cacheControl ( );
        // 添加JWT filter
        http.addFilterBefore ( jwtAuthenticationTokenFilter ( ),UsernamePasswordAuthenticationFilter.class );
        //添加自定义未授权和未登录结果返回
        http.exceptionHandling ( )
                .accessDeniedHandler ( restfulAccessDeniedHandler )
                .authenticationEntryPoint ( restAuthenticationEntryPoint );
    }

}

